/*
** Copyright (C) 2009 Joshua Brent Marsh <joshua@icub3d.com>
**  
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation; either version 3 of the License, or
** (at your option) any later version.
**  
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
** GNU General Public License for more details.
**  
** You should have received a copy of the GNU General Public License
** along with this program; if not, write to the Free Software
** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
**  
*/

/* $Id: test_list_sort.c 43 2009-11-13 23:27:38Z joshua@icub3d.com $ */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <stdlib.h>
#include <stdio.h>
#include <malloc.h>

#include <CUnit/Basic.h>

#include "../src/list.h"
#include "../src/list_sort.h"
#include "../src/function_prototypes.h"

#include "test_helpers.h"
#include "test_list_sort.h"

int
init_test_list_sort_suite ()
{
  return 0;
}

int
clean_test_list_sort_suite ()
{
  return 0;
}

void
test_list_sort_bubble()
{
  List *l;
  int x;
  int *cur;

  l = list_create_circular ();

  /* Insert items into the list. */
  for (x = 9; x >= 0; x--)
    {
      cur = create_int (x);
      CU_ASSERT (list_insert_last (l, cur) == 1);
    } 

  /* Make sure the list is in the wrong order. */
  for (x = 0; x < 10; x++)
    {
      CU_ASSERT (*(int *)list_get (l, x) == 9 - x);
    }


  bubble_sort (l, comp_int);

  /* Make sure the list is in the right order. */
  for (x = 0; x < 10; x++)
    {
      CU_ASSERT (*(int *)list_get (l, x) == x);
    }

  list_destroy (l, dest_int);
}

void
test_list_sort_selection()
{
  List *l;
  int x;
  int *cur;

  l = list_create_circular ();

  /* Insert items into the list. */
  for (x = 9; x >= 0; x--)
    {
      cur = create_int (x);
      CU_ASSERT (list_insert_last (l, cur) == 1);
    } 

  /* Make sure the list is in the wrong order. */
  for (x = 0; x < 10; x++)
    {
      CU_ASSERT (*(int *)list_get (l, x) == 9 - x);
    }


  selection_sort (l, comp_int);

  /* Make sure the list is in the right order. */
  for (x = 0; x < 10; x++)
    {
      CU_ASSERT (*(int *)list_get (l, x) == x);
    }

  list_destroy (l, dest_int);
}

void
test_list_sort_insertion()
{
  List *l;
  int x;
  int *cur;

  l = list_create_circular ();

  /* Insert items into the list. */
  for (x = 9; x >= 0; x--)
    {
      cur = create_int (x);
      CU_ASSERT (list_insert_last (l, cur) == 1);
    } 

  cur = create_int (10);
  CU_ASSERT (list_insert_last (l, cur) == 1);

  /* Make sure the list is in the wrong order. */
  for (x = 0; x < 10; x++)
    {
      CU_ASSERT (*(int *)list_get (l, x) == 9 - x);
    }
  CU_ASSERT (*(int *)list_get (l, 10) == 10);

  insertion_sort (l, comp_int);

  for (x = 0; x < 10; x++)
    {
      CU_ASSERT (*(int *)list_get (l, x) == x);
    }
  CU_ASSERT (*(int *)list_get (l, 10) == 10);

  /* Make sure the list is in the right order. */
  list_destroy (l, dest_int);

  /* Make sure that an empty list doesn't blow up. */
  l = list_create_circular ();
  CU_ASSERT (l != NULL);
  
  insertion_sort (l, comp_int);
  CU_ASSERT (list_size (l) == 0);
  CU_ASSERT (l->head == NULL);
  CU_ASSERT (l->tail == NULL);

  list_destroy (l, NULL);
}

int
make_list_sort_suite (CU_pSuite s)
{
  s = CU_add_suite ("Test List_Sort Suite", 
		    init_test_list_sort_suite, 
		    clean_test_list_sort_suite);
  if (s == NULL)
    {
      return CU_get_error();
    }

  if (CU_add_test (s, "test list_sort_bubble's", 
		   test_list_sort_bubble) == NULL ||
      CU_add_test (s, "test list_sort_selection's", 
		   test_list_sort_selection) == NULL ||
      CU_add_test (s, "test list_sort_insertion's", 
		   test_list_sort_insertion) == NULL)
    {
      return CU_get_error();
    }

  return CU_get_error();
}
